package cn.songhaiqing.walle.bledemo;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.json.JSONException;
import org.json.JSONObject;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import cn.songhaiqing.walle.Event.HeartStatusEvent;
import cn.songhaiqing.walle.Event.MqttEvent;
import cn.songhaiqing.walle.bean.Heart;
import cn.songhaiqing.walle.bean.MyApp;
import cn.songhaiqing.walle.ble.activity.DeviceScanActivity;
import cn.songhaiqing.walle.ble.service.WalleBleService;
import cn.songhaiqing.walle.ble.utils.BleUtil;
import cn.songhaiqing.walle.ble.utils.LogUtil;
import cn.songhaiqing.walle.ble.utils.StringUtil;
import cn.songhaiqing.walle.ble.utils.WalleBleConfig;
import cn.songhaiqing.walle.ble_controller.NoConnectException;
import cn.songhaiqing.walle.help.DeviceHelper;
import cn.songhaiqing.walle.help.FormatHelper;
import cn.songhaiqing.walle.help.ParserHelper;
import cn.songhaiqing.walle.help.SpHelper;
import cn.songhaiqing.walle.help.VersionHelper;
import cn.songhaiqing.walle.service.BLEService2;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private final String TAG = getClass().getName();
    private final int REQUEST_BIND_DEVICE = 1;

    private Button btnDisconnect;
    private Button btnScan;
    private TextView tvInfo;
    private TextView tvLog;
    //心率值
    private TextView tv_heart_value;
    //步数
    private TextView tv_step_count;
    //睡眠
    private TextView tv_sleep;
    //血压
    private TextView tv_blood_child_data;
    //呼吸值
    private TextView tv_huxi_num;
    private int mqttStatus = 2;
    private ArrayList<String> listTime = new ArrayList<>();
    private ArrayList<String> listValue = new ArrayList<>();

    private String bleName;
    private String bleAddress = "DD:C3:BE:67:C1:16";
    private int heart_test_status = 0;
    private ArrayList<Heart> heartList = new ArrayList<>();
    private Runnable startHeartValue = new Runnable() {
        /* class com.gzgamut.smart_movement.main.HrvFragment.AnonymousClass3 */

        public void run() {
            BLEService2 service2 = MyApp.getIntance().mService2;
            if (service2 != null) {
                try {
                    service2.set_heart((byte) 0);
                } catch (NoConnectException e) {
                    e.printStackTrace();
                }
                MainActivity.this.handler.postDelayed(MainActivity.this.startHeartValue, 1000);
            }
        }
    };
    private Runnable getHeartValue = new Runnable() {
        /* class com.gzgamut.smart_movement.main.HeartFragment2.AnonymousClass5 */

        public void run() {
            BLEService2 service2 = MyApp.getIntance().mService2;
            if (service2 != null) {
                try {
                    service2.set_heart((byte) 2);
                    MainActivity.this.start();
                } catch (NoConnectException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    public static int initProfileID(Context applicationContext) {
        return 0;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        EventBus.getDefault().register(this);

        btnDisconnect = findViewById(R.id.btn_disconnect);
        btnScan = findViewById(R.id.btn_scan);
        tvInfo = findViewById(R.id.tv_info);
        tvLog = findViewById(R.id.tv_log);
        tv_heart_value = findViewById(R.id.tv_heart_num);
        tv_blood_child_data = findViewById(R.id.tv_blood_child_data);
        tv_sleep = findViewById(R.id.tv_sleep);
        tv_huxi_num = findViewById(R.id.tv_huxi_num);
        tv_step_count = findViewById(R.id.tv_step_count);

        autoConnection();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(WalleBleService.ACTION_CONNECTED_SUCCESS);
        intentFilter.addAction(WalleBleService.ACTION_GATT_DISCONNECTED);
        intentFilter.addAction(WalleBleService.ACTION_DEVICE_RESULT);
        intentFilter.addAction(WalleBleService.ACTION_SERVICES_DISCOVERED_DONE);
        registerReceiver(bleReceiver, intentFilter);

        btnDisconnect.setOnClickListener(this);
        btnScan.setOnClickListener(this);

        WalleBleConfig.setDebug(true);
        WalleBleConfig.setBleResultWaitTime(10000);
        //autoConnection();
        loadStatusInfo();

    }

    private Handler handler = new Handler() {
        /* class com.gzgamut.smart_movement.main.HeartFragment2.AnonymousClass1 */

        public void handleMessage(Message msg) {
            switch (msg.what) {
                case 0:
                    if (MainActivity.this.heartList.size() > 60) {
                        MainActivity.this.heartList.remove(MainActivity.this.heartList.size() - 1);
                    }
                    MainActivity.this.tv_heart_value.setText(String.valueOf(((Heart) MainActivity.this.heartList.get(0)).getHeart()));
                    //MainActivity.this.showDayChart(MainActivity.this.heartList);
                    return;
                case 1:
                    MainActivity.this.heartList.clear();
                    //MainActivity.this.showDayChart(HeartFragment2.this.heartList);
                    // MainActivity.this.isStart_JudgeUi(true);
                    return;
                case 2:
                    // MainActivity.this.stopHeartTest();
                    return;
                default:
                    return;
            }
        }
    };


    private void loadStatusInfo() {
        int status = BleUtil.getConnectStatus();
        String info;
        if (status == BleUtil.CONNECT_STATUS_SUCCESS) {
            info = bleName + "(" + bleAddress + ") " + getString(R.string.device_status_connected);
        } else if (status == BleUtil.CONNECT_STATUS_CONNECTING) {
            info = bleName + "(" + bleAddress + ") " + getString(R.string.device_status_connecting);
        } else if (status == BleUtil.CONNECT_STATUS_FAIL) {
            info = bleName + "(" + bleAddress + ") " + getString(R.string.device_status_connection_fail);
        } else {
            info = getString(R.string.device_not_connected);
        }
        tvInfo.setText(info);
    }

    private void autoConnection() {
        String address = "DD:C3:BE:67:C1:16";
        if (TextUtils.isEmpty(address)) {
            return;
        }
        BleUtil.connectDevice(this, address);
    }

    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onDataSynEvent(HeartStatusEvent event) {
        byte[] value = event.getValue();
        int second = ParserHelper.getByteValue(value[1]);
        int third = ParserHelper.getByteValue(value[2]);
        switch (second) {
            case 0:
                if (third == 0) {
                    this.handler.removeCallbacks(this.startHeartValue);
                    start();
                    return;
                }
                // ToastHelper.getInstance(getContext()).showToast("开启心率测量失败");
                return;
            case 1:
                if (third == 0) {
                    //this.handler.removeCallbacks(this.stopHeartValue);
                    return;
                } else {
                    // ToastHelper.getInstance(getContext()).showToast("关闭心率测量失败");
                    return;
                }
            case 2:
                getHeart(third);
                return;
            case 3:
            case 4:
            default:
                return;
            case 5:
               /* if (!this.isInForceground) {
                    return;
                }*/
                if (third == 1) {
                    this.handler.sendEmptyMessage(1);
                    // startHeartTestByBound();
                    return;
                }
                this.handler.sendEmptyMessage(2);
                return;
            case 6:
                //setVibrate(true);
                return;
        }
    }

    private void start() {
        this.handler.postDelayed(this.getHeartValue, 1000);
    }

    private void getHeart(int third) {
        if (this.heart_test_status != 0 && third >= 39 && third <= 200) {
            Calendar cal = Calendar.getInstance();
            Heart heart = new Heart();
            heart.setDate(cal);
            heart.setHeart(third);
            heart.setVersion(VersionHelper.getVersionWatch());
           /* int profileID = DatabaseProvider.getProfileID(getActivity());
            if (DatabaseProvider.getInstance(getActivity().getApplicationContext()).queryHeart(getActivity(), profileID, cal) == null) {
                DatabaseProvider.getInstance(getActivity().getApplicationContext()).insertSingleHeart(getActivity(), profileID, heart);
            } else {
                DatabaseProvider.getInstance(getActivity().getApplicationContext()).updateHeart(getActivity(), profileID, heart);
            }*/
            this.heartList.add(0, heart);
            if (this.listValue == null) {
                this.listValue = new ArrayList<>();
            }
            if (this.listTime == null) {
                this.listTime = new ArrayList<>();
            }
            this.listValue.add(String.valueOf(third));
            this.listTime.add(FormatHelper.sdf_yyyy_MM_dd_HH_mm_ss.format(cal.getTime()));
            this.handler.sendEmptyMessage(0);
        }
    }

    private BroadcastReceiver bleReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (intent.getStringExtra("uuid") != null) {
                addLog(intent.getStringExtra("uuid"));
            }
            if (intent.getByteArrayExtra("srcData") != null) {
                byte[] srcData = intent.getByteArrayExtra("srcData");
                String hex = StringUtil.bytesToHexStr(srcData);
                addLog(hex);
            }
            Log.d(TAG, action);
            if (WalleBleService.ACTION_SERVICES_DISCOVERED_DONE.equals(action)) {
                addLog("连接成功");
            } else if (WalleBleService.ACTION_GATT_DISCONNECTED.equals(action)) {
                loadStatusInfo();
                addLog("断开连接");
            } else if (WalleBleService.ACTION_DEVICE_RESULT.equals(action)) {
                // 特征值UUID
                String uuid = intent.getStringExtra("uuid");
                // 十进制内容
                ArrayList<Integer> dataArray = intent.getIntegerArrayListExtra("data");
                // byte原内容
                byte[] srcData = intent.getByteArrayExtra("srcData");
                String hex = StringUtil.bytesToHexStr(srcData);
                LogUtil.d(TAG, "十六进制结果：" + hex);
                addLog(hex);
            }
        }
    };

    private void addLog(String content) {
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        tvLog.append("\n" + sdf.format(new Date()) + " " + content);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK && REQUEST_BIND_DEVICE == requestCode) {
            bleName = data.getStringExtra("name");
            bleAddress = data.getStringExtra("macAddress");
            addLog("开始连接设备 " + bleName + "(" + bleAddress + ")");
            BleUtil.connectDevice(this, bleAddress);
            loadStatusInfo();
        }
    }

    @Override
    protected void onDestroy() {
        BleUtil.disConnect(this);
        unregisterReceiver(bleReceiver);
        super.onDestroy();
    }

    @Override
    public void onClick(View view) {
        final int id = view.getId();
        switch (id) {
            case R.id.btn_scan:
                Intent intent = new Intent(this, DeviceScanActivity.class);
                intent.putExtra("showSignalStrength", false);
                startActivityForResult(intent, REQUEST_BIND_DEVICE);
                break;
            case R.id.btn_disconnect:
                BleUtil.disConnect(this);
                break;
        }
    }

    public void onClear(View v) {
        tvLog.setText("");
    }

    /**
     * 发送命令，示例内容根据实际情况修改测试，支持消息队列。
     *
     * @param v
     */
    public void onSendCmd(View v) {


    }

    public void onPrlStart(View v) {
        Toast.makeText(this, "同步心率", Toast.LENGTH_SHORT).show();
        //  DeviceHelper.newSaveDeviceName("KEY_DEFALUT_DEVICE");
        SpHelper.putInt("KEY_DEFALUT_DEVICE", 3);
        startHeartTest();
    }

    private void startHeartTest() {
        /*if (DeviceHelper.isSH08() || DeviceHelper.isI3()) {
            Toast.makeText(this, "本型号不支持此功能", Toast.LENGTH_SHORT).show();
            return;
        }*/
        BLEService2 service2 = MyApp.getIntance().mService2;
        if (service2 == null) {
            return;
        }
        service2.connectMqttForHrv();
        service2.connect(bleAddress);
       /* if (service2.getConnectState() != 0) {
            Toast.makeText(this, "Dialog_Please_connect_to_your_band_firstly", Toast.LENGTH_SHORT).show();
        } else if (service2.getIsSync()) {
            Toast.makeText(this, "同步中，请稍等", Toast.LENGTH_SHORT).show();
        } else if (this.heart_test_status == 0) {*/
        this.heartList.clear();
        //this.listValue.clear();
        //this.listTime.clear();
        // showDayChart(this.heartList);
        //isStart_JudgeUi(true);
        this.heart_test_status = 1;
        //   service2.set_heart((byte) 0);
        addLog("startHeartValue= " + "(" + this.startHeartValue + ")");
        this.handler.postDelayed(this.startHeartValue, 1000);
        //}
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onDataSynEvent(MqttEvent event) {
        BLEService2 service2 = MyApp.getIntance().mService2;
        if (service2 != null) {
            String mac = DeviceHelper.getBoundDeviceAddress();
            if (mac == null) {
                mac = "DD:C3:BE:67:C1:16";
            }
            switch (event.getStatue()) {
                case 1:
                    this.mqttStatus = 1;
                    service2.subscribeTopic(BLEService2.SubscribeTopic + mac);
                    return;
                case 2:
                    this.mqttStatus = 2;
                    reConnectMqtt();
                    return;
                case 3:
                    this.mqttStatus = 3;
                    reConnectMqtt();
                    return;
                case 4:
                    letMqttStart();
                    return;
                case 5:
                    reSubscribeMqtt(BLEService2.SubscribeTopic + mac);
                    return;
                case 6:
                case 7:
                default:
                    return;
                case 8:
                    //startTestHeart();
                    return;
                case 9:
                    // reStart();
                    return;
            }
        } else {
            //stopHrvTest();
        }
    }

    private void reSubscribeMqtt(String topic) {
        BLEService2 service2;
        if (this.mqttStatus == 1 && (service2 = MyApp.getIntance().mService2) != null) {
            if (this.disSubscribeCount < 5) {
                this.disSubscribeCount++;
                service2.subscribeTopic(topic);
                return;
            }
            this.disSubscribeCount = 0;
            //stopHrvTest();
            //ToastHelper.getInstance(getContext()).showToast("无法连接服务器");
        }
    }


    public static final String KEYDEVMAC = "devMac";
    public static final String VALUEACTION = "start";

    private void letMqttStart() {
        try {
            String mac = DeviceHelper.getBoundDeviceAddress();
            DeviceHelper.getDeviceName();
            JSONObject mes = new JSONObject();
            mes.put(KEYDEVMAC, mac);
            mes.put("action", VALUEACTION);
            MqttMessage message = new MqttMessage(mes.toString().getBytes());
            message.setId(3);
            message.setQos(2);
            publishMessge(message);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void publishMessge(MqttMessage message) {
        BLEService2 service2 = MyApp.getIntance().mService2;
        if (service2 != null && this.mqttStatus == 1) {
            service2.publishMessge(message);
        }
    }

    private int disConnectedCount = 0;
    private int disSubscribeCount = 0;

    private void reConnectMqtt() {
        BLEService2 service2 = MyApp.getIntance().mService2;
        if (service2 == null) {
            return;
        }
        if (this.disConnectedCount < 5) {
            this.disConnectedCount++;
            service2.connectMqttForHrv();
            return;
        }
        this.disConnectedCount = 0;
        //stopHrvTest();
        //ToastHelper.getInstance(getContext()).showToast("无法连接服务器");
    }
}
